﻿using System;
using System.Threading;
using CommonLibrary.Helpers;

namespace CommonLibrary.Models.ControllerStates.PS3
{
    /* PS3 State */
    public class SixaxisStateSys
    {
        /*** Values provided by the system (PS3): */
        public int ReportingEnabled;
        public int FeatureEfByte6;

        /* led[0] is the spare */
        /* led[1]..led[4] correspond to printed text 1..4 */
        public LedState[] Led = new LedState[5];
        public ushort[] Rumble = new ushort[2];
    }

    public enum LedState
    {
        LedOff = 0,
        LedFlash = 1,
        LedOn = 2
    };

    /* User State */
    public class SixaxisStateUser : ViewModel
    {
        // TODO Add a better Handler for the controller state
        private static Mutex mutAxis1 = new Mutex();
        private static Mutex mutAxis2 = new Mutex();
        private static Mutex mutAxis3 = new Mutex();
        private static Mutex mutAxis4 = new Mutex();

        /*** Values provided by the user (controller): */
        private static SixAxisButtons _buttons;
        public SixAxisButtons Buttons
        {
            get { return _buttons ?? (_buttons = new SixAxisButtons()); }
            set { _buttons = value;
            OnPropertyChanged("Buttons");}
        }

        private ushort _lAxisX = ushort.MaxValue / 2;
        public UInt16 LAxisX
        {
            get { return _lAxisX; }
            set
            {
                mutAxis1.WaitOne(); _lAxisX = value; OnPropertyChanged("LAxisX"); mutAxis1.ReleaseMutex(); }
        }

        private ushort _lAxisY = ushort.MaxValue / 2;
        public UInt16 LAxisY
        {
            get { return _lAxisY; }
            set
            {
                mutAxis2.WaitOne(); _lAxisY = value; OnPropertyChanged("LAxisY");  mutAxis2.ReleaseMutex();}
        }

        private ushort _rAxisX = ushort.MaxValue / 2;
        public UInt16 RAxisX
        {
            get { return _rAxisX; }
            set
            {
                mutAxis3.WaitOne(); _rAxisX = value; OnPropertyChanged("RAxisX"); mutAxis3.ReleaseMutex(); }
        }

        private ushort _rAxisY = ushort.MaxValue / 2;
        public UInt16 RAxisY
        {
            get { return _rAxisY; }
            set
            {
                mutAxis4.WaitOne(); _rAxisY = value; OnPropertyChanged("RAxisY"); mutAxis4.ReleaseMutex(); }
        }


        public SixaxisAccelerometer Accelerometer;
    };

    public class SixaxiButton : ViewModel
    {
        /* It's possible for a button to report as being pressed but still have a zero value */
        private bool _pressed;
        public bool Pressed
        {
            get { return _pressed; }
            set
            {
                _pressed = value;
                OnPropertyChanged("Pressed");
            }
        }

        /* 0 to 255 */
        private byte _value;
        public byte Value
        {
            get { return _value; }
            set
            {
                _value = value;
                OnPropertyChanged("Value");
            }
        }
    }

    public struct SixaxisAccelerometer
    {
        /* -512 to 511 */
        public int X;
        public int Y;
        public int Z;
        public int Gyro;
    };
}
